package zadanie4;
import java.util.ArrayList;


public class Zadanie  {

	public Zadanie(ArrayList<Integer> list , Window parent) {
		super();
		this.list = list;
		this.table = new int[256];
		this.parent = parent;
	}
	private Window parent;
	private ArrayList<Integer> list;
	private int[] table;
	private int threadNumber;
	private boolean semafor = false;
	private long startTime;
	private long countingTime;
	private ArrayList<MyThread> myThreads;
	

	 public long getCountingTime() {
		return countingTime;
	}
	
	public ArrayList<MyThread> getMyThreads() {
		return myThreads;
	}

	public void setMyThreads(ArrayList<MyThread> myThreads) {
		this.myThreads = myThreads;
	}

	public void setCountingTime(long countingTime) {
		this.countingTime = countingTime;
	}

	public long getStartTime() {
		return startTime;
	}

	public void setStartTime(long startTime) {
		this.startTime = startTime;
	}

	public int[] getTable() {
		return table;
	}

	public void setTable(int[] table) {
		this.table = table;
	}

	public boolean isSemafor() {
		return semafor;
	}

	public synchronized boolean setSemafor() {
		if(semafor == false ){
			this.semafor = true;
			return true;
		}else
			return false;
	}

	public int getThreadNumber() {
		return threadNumber;
	}

	public void setThreadNumber(int threadNumber) {
		this.threadNumber = threadNumber;
	}
	public synchronized void decrementhreadNumber() {
		--this.threadNumber;
		if(threadNumber == 0 ){
			setCountingTime(System.currentTimeMillis() - getStartTime());
			if(parent instanceof onCountingComplete)
				parent.CountingComplete();
		}
	}

	public synchronized void incHistogram(int index){
		 ++table[index];
	 }
	
	public void histogramCalculation(int start, int end){		
		for(int i = start; i < end; i ++){
			incHistogram(list.get(i).intValue());
		}
	}
	public void start(int thread_number) {
		clearTable();
		setThreadNumber(thread_number);		
		if(thread_number < 2 ){
			setStartTime(System.currentTimeMillis());
			histogramCalculation(0, list.size());
			setCountingTime(System.currentTimeMillis() - getStartTime());
			if(parent instanceof onCountingComplete)
				parent.CountingComplete();
			}
		else{
			myThreads = new ArrayList<Zadanie.MyThread>();
			int tmp = list.size()/thread_number;
			int start = 0;
			setStartTime(System.currentTimeMillis());
			for(int i = 0 ; i < thread_number;i++){
				myThreads.add(new MyThread(start, start + tmp) );
				start += tmp;
		}	
	}		
  }
	
	class MyThread extends Thread {
		
		int start_index;
		int end_index;
		long threadCountingTime;
		long threadStartTime;
				
		public MyThread(int start_index, int end_index) {
			super();
			this.start_index = start_index;
			this.end_index = end_index;
			start();
		}

		@Override
		public void run() {
			threadStartTime = System.currentTimeMillis();
			histogramCalculation(start_index, end_index);
			threadCountingTime = System.currentTimeMillis() - threadStartTime;
			decrementhreadNumber();
		}	
		public long getThreadCountingTime(){
			return threadCountingTime;
		}

	}
	
	public void clearTable(){
		for(int i = 0 ; i < 256; i++){
			table[i]=0;
		}
	}

	
}
	
